﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Kiiro.Common.Entities;
using Kiiro.Common.Utility;
using Kiiro.Validation.Interfaces;

namespace Kiiro.Validation.Validators.Entities
{
    public class SetupValidator : BaseEntityValidator, IValidator<Setup>
    {
        private readonly List<ValidationMessage> validationErrors = new List<ValidationMessage> ( );

        #region  IValidator<Setup> Members
        public List<ValidationMessage> Validate ( Setup entityToValidate )
        {
            // If the entity is marked as deleted, don't do any validation, just return.
            if ( entityToValidate.EditType != EditType.Deleted )
            {
                ValidationMessage message = null;

                #region Required Fields Checks

                message = IsRequired ( entityToValidate.SiteName, "Site Name" );

                if ( message != null )
                {
                    entityToValidate.SiteNameMessage.Add ( message );
                    validationErrors.Add ( message );
                }


                if ( ( entityToValidate.SendEmailUpdates && entityToValidate.AllowEmailReplies ) || entityToValidate.AllowEmailReplies )
                {
                    message = IsRequired ( entityToValidate.SMTPInfo, "SMTP Info" );

                    if ( message != null )
                    {
                        entityToValidate.SMTPInfoMessage.Add ( message );
                        validationErrors.Add ( message );
                    }

                    message = IsRequired ( entityToValidate.EmailFromAddress, "Email From Address" );

                    if ( message != null )
                    {
                        entityToValidate.EmailFromAddressMessage.Add ( message );
                        validationErrors.Add ( message );
                    }

                    message = IsRequired ( entityToValidate.POPInfo, "POP Info" );

                    if ( message != null )
                    {
                        entityToValidate.POPInfoMessage.Add ( message );
                        validationErrors.Add ( message );
                    }

                    message = IsRequired ( entityToValidate.POPEmail, "POP Email" );

                    if ( message != null )
                    {
                        entityToValidate.POPEmailMessage.Add ( message );
                        validationErrors.Add ( message );
                    }

                    message = IsRequired ( entityToValidate.POPPassword, "POP Password" );

                    if ( message != null )
                    {
                        entityToValidate.POPPasswordMessage.Add ( message );
                        validationErrors.Add ( message );
                    }
                }
                else if ( entityToValidate.SendEmailUpdates )
                {

                    message = IsRequired ( entityToValidate.SMTPInfo, "SMTP Info" );

                    if ( message != null )
                    {
                        entityToValidate.SMTPInfoMessage.Add ( message );
                        validationErrors.Add ( message );
                    }

                    message = IsRequired ( entityToValidate.EmailFromAddress, "Email From Address" );

                    if ( message != null )
                    {
                        entityToValidate.EmailFromAddressMessage.Add ( message );
                        validationErrors.Add ( message );
                    }
                }

                #endregion

                #region Comparison Checks

                if ( !string.IsNullOrEmpty ( entityToValidate.SiteName ) )
                {
                    message = CheckMaximumLength ( 255, entityToValidate.SiteName, "Site Name" );

                    if ( message != null )
                    {
                        entityToValidate.SiteNameMessage.Add ( message );
                        validationErrors.Add ( message );
                    }

                    message = HasScriptingTagsInText ( entityToValidate.SiteName, "Site Name" );

                    if ( message != null )
                    {
                        entityToValidate.SiteNameMessage.Add ( message );
                        validationErrors.Add ( message );
                    }
                }

                if ( entityToValidate.LogoBytes != null )
                {
                    message = ValidateImageDimensions ( entityToValidate.LogoBytes );

                    if ( message != null )
                    {
                        entityToValidate.LogoBytesMessage.Add ( message );
                        validationErrors.Add ( message );
                    }
                }
                
                if ( !string.IsNullOrEmpty ( entityToValidate.EmailFromAddress ) )
                {
                    message = IsEmailValid ( entityToValidate.EmailFromAddress, "System Email" );

                    if ( message != null )
                    {
                        entityToValidate.EmailFromAddressMessage.Add ( message );
                        validationErrors.Add ( message );
                    }
                    //else
                    {
                        message = CheckMaximumLength ( 255, entityToValidate.EmailFromAddress, "System Email" );

                        if ( message != null )
                        {
                            entityToValidate.EmailFromAddressMessage.Add ( message );
                            validationErrors.Add ( message );
                        }

                        message = HasScriptingTagsInText ( entityToValidate.EmailFromAddress, "System Email" );

                        if ( message != null )
                        {
                            entityToValidate.EmailFromAddressMessage.Add ( message );
                            validationErrors.Add ( message );
                        }
                    }
                }

                if ( !string.IsNullOrEmpty ( entityToValidate.SMTPInfo ) )
                {
                    message = CheckMaximumLength ( 255, entityToValidate.SMTPInfo, "SMTP Info" );

                    if ( message != null )
                    {
                        entityToValidate.SMTPInfoMessage.Add ( message );
                        validationErrors.Add ( message );
                    }

                    message = HasScriptingTagsInText ( entityToValidate.SMTPInfo, "SMTP Info" );

                    if ( message != null )
                    {
                        entityToValidate.SMTPInfoMessage.Add ( message );
                        validationErrors.Add ( message );
                    }
                }

                if ( !string.IsNullOrEmpty ( entityToValidate.POPInfo ) )
                {
                    message = CheckMaximumLength ( 255, entityToValidate.POPInfo, "POP Info" );

                    if ( message != null )
                    {
                        entityToValidate.POPInfoMessage.Add ( message );
                        validationErrors.Add ( message );
                    }

                    message = HasScriptingTagsInText ( entityToValidate.POPInfo, "POP Info" );

                    if ( message != null )
                    {
                        entityToValidate.POPInfoMessage.Add ( message );
                        validationErrors.Add ( message );
                    }
                }

                if ( !string.IsNullOrEmpty ( entityToValidate.POPEmail ) )
                {
                    message = IsEmailValid ( entityToValidate.POPEmail, "POP Email" );

                    if ( message != null )
                    {
                        entityToValidate.POPEmailMessage.Add ( message );
                        validationErrors.Add ( message );
                    }
                    //else
                    {
                        message = CheckMaximumLength ( 255, entityToValidate.POPEmail, "POP Email" );

                        if ( message != null )
                        {
                            entityToValidate.POPEmailMessage.Add ( message );
                            validationErrors.Add ( message );
                        }

                        message = HasScriptingTagsInText ( entityToValidate.POPEmail, "POP Email" );

                        if ( message != null )
                        {
                            entityToValidate.POPEmailMessage.Add ( message );
                            validationErrors.Add ( message );
                        }
                    }
                }

                if ( !string.IsNullOrEmpty ( entityToValidate.POPPassword ) )
                {
                    message = CheckMaximumLength ( 255, entityToValidate.POPPassword, "POP Password" );

                    if ( message != null )
                    {
                        entityToValidate.POPPasswordMessage.Add ( message );
                        validationErrors.Add ( message );
                    }

                    message = HasScriptingTagsInText ( entityToValidate.POPPassword, "POP Password" );

                    if ( message != null )
                    {
                        entityToValidate.POPPasswordMessage.Add ( message );
                        validationErrors.Add ( message );
                    }
                }

                if ( !string.IsNullOrEmpty ( entityToValidate.LicenseKey ) )
                {
                    message = CheckMaximumLength ( 5000, entityToValidate.LicenseKey, "License Key" );

                    if ( message != null )
                    {
                        entityToValidate.LicenseKeyMessage.Add ( message );
                        validationErrors.Add ( message );
                    }

                    message = HasScriptingTagsInText ( entityToValidate.LicenseKey, "License Key" );

                    if ( message != null )
                    {
                        entityToValidate.LicenseKeyMessage.Add ( message );
                        validationErrors.Add ( message );
                    }
                }

                if (entityToValidate.HoursPerDay < 0.1 || entityToValidate.HoursPerDay > 24)
                {
                    message = new ValidationMessage(ValidationSeverity.Validation, "Hours Per Day must be greater than 0 and less than 24.");
                    entityToValidate.HoursPerDayMessage.Add(message);
                    validationErrors.Add(message);
                }

                if ( entityToValidate.IsWPSandboxActivated )
                {
                    message = IsRequired ( entityToValidate.WPSandboxNavText, "Tab Text" );

                    if ( message != null )
                    {
                        entityToValidate.WPSandboxNavTextMessage.Add ( message );
                        validationErrors.Add ( message );
                    }

                    if ( !string.IsNullOrEmpty ( entityToValidate.WPSandboxNavText ) )
                    {
                        message = CheckMaximumLength ( 30, entityToValidate.WPSandboxNavText, "Tab Text" );

                        if ( message != null )
                        {
                            entityToValidate.WPSandboxNavTextMessage.Add ( message );
                            validationErrors.Add ( message );
                        }

                        message = HasScriptingTagsInText ( entityToValidate.WPSandboxNavText, "Tab Text" );

                        if ( message != null )
                        {
                            entityToValidate.WPSandboxNavTextMessage.Add ( message );
                            validationErrors.Add ( message );
                        }
                    }

                #endregion

                }
            }

            return validationErrors;
        }

        #endregion

        private ValidationMessage IsRequired ( Version value, string propertyName )
        {
            ValidationMessage message = null;

            if ( value == default ( Version ) )
            {
                message = new ValidationMessage ( ValidationSeverity.Validation, string.Format ( "{0} is a required field.", propertyName ) );
            }
            return message;
        }

        private ValidationMessage VerifyFileExtension ( string value )
        {
            ValidationMessage message = null;
            if ( !VerifyImageFileExtension ( value ) )
            {
                message = new ValidationMessage ( ValidationSeverity.Validation, "Invalid file extension. File must be a .JPG or .PNG file." );
            }
            return message;
        }

        private bool VerifyImageFileExtension ( string fileName )
        {
            string extension = System.IO.Path.GetExtension ( fileName );
            return ( extension.ToUpper ( ) == ".JPG" || extension.ToUpper ( ) == ".PNG" );
        }

        private ValidationMessage VerifyFileSize ( byte [ ] value )
        {
            ValidationMessage message = null;
            if ( !VerifyImageFileSize ( value ) )
            {
                message = new ValidationMessage ( ValidationSeverity.Validation, "File size has to be less than 10 MB." );
            }
            return message;
        }

        private bool VerifyImageFileSize ( byte[] file )
        {
            MemoryStream memoryStream = new MemoryStream ( file );
            int fileSize = memoryStream.Capacity;
            // Allow only files less than 10,100,000 bytes (approximately 10 MB) to be uploaded.
            return ( fileSize < 10100000 );
        }

        private ValidationMessage ValidateImageDimensions(byte[] siteLogo)
        {
            bool validDimensions = true;

            MemoryStream stream = new MemoryStream(siteLogo);
            System.Drawing.Image img = System.Drawing.Image.FromStream(stream);

            int sourceWidth = img.Width;
            int sourceHeight = img.Height;

            if (sourceHeight > 30)
                validDimensions = false;
            else if (sourceWidth > 90)
                validDimensions = false;

            ValidationMessage message = null;
            if (!validDimensions)
            {
                message = new ValidationMessage(ValidationSeverity.Validation, "Invalid Image file. Image must be a maximum 280 pixels wide and 64 pixels tall.");
            }
            return message;
        }
    }
}

/*************************************************************************
 * 
 * $Log: /Internal Projects/Kiiro/Kiiro.Validation/Validators/Entities/SetupValidator.cs $
 * 
 * 10    26/11/09 10:02a Camerons
 * 
 * 9     10/26/09 11:08a Adamw
 * Case 332
 * 
 * 8     19/10/09 12:33p Shafia
 * 
 * 7     17/08/09 10:45a Camerons
 * Added check-in comments section
 * 
 ************************************************************************/